import { RequestCodeMessage } from '@/common/constVariable';
import MyIcon from '@/components/MyIcon';
import { loadMdicMap } from '@/services/BaseLayout';
import { getBaseUrl, getPrinterUrl } from '@/services/urlconst';
import { Col, Row, Tooltip, message, notification } from 'antd';
import { groupBy } from 'lodash';
import moment from 'moment';
import { ReactElement, useMemo } from 'react';
import { useRequest } from 'umi';
import { getCompanyID, getPersonalInfo, getPosIDs, getTenant, getTenantID, getUserDepID, getUserID, getUserName } from './authority';
import { DecryptIv, EncryptIv } from './crypto';
import { resetUrl } from './request';
import pageStyles from '@/common/pageLayout.less';
import { CaretDownOutlined, CaretRightOutlined } from '@ant-design/icons';
import Watermark from 'watermark-dom';
import { ILoadMapTypeAll } from '@/common';

// 下拉选择数据字典 ，icon 传入title 前所需展示图标  <MyIcon type = ''/>
export function treeSelectIconTransform(arr: any, icon: any) {
  let data = Array.isArray(arr) ? arr : [];
  return data.map((item) => {
    const result: any = {
      title: (
        <span>
          <span style={{ marginRight: 2 }}>{icon}</span> {item.text || item.name}
        </span>
      ),
      value: item.id,
      key: item.id,
      deptId: item.departmentID,
      childrens: item.children ? item.children : [],
      isLeaf: item.children ? false : true,
      searchTitle: item.text || item.name,
    };
    if (item.children) {
      result.children = treeSelectIconTransform(item.children, icon);
    }
    return result;
  });
}

// 平铺树数据方法, 主要为了AutoComplete 使用
export const loopArray = (array: any[]): Record<string, any>[] => {
  const tileArray: Record<string, any>[] = [];
  const loop = (data: any[]) => {
    data?.forEach((item) => {
      if (item?.children && item?.children?.length > 0) {
        loop(item?.children);
      }
      tileArray.push({ ...item, children: null });
    });
  };
  loop(array?.length > 0 ? array : []);
  return tileArray;
};

// 平铺树数据方法, 每个节点都回包含 自己的children
export const loopArrayChildren = (array: any[]): Record<string, any>[] => {
  const tileArray: Record<string, any>[] = [];
  const loop = (data: any[]) => {
    data?.forEach((item) => {
      if (item?.children && item?.children?.length > 0) {
        loop(item?.children);
      }
      tileArray.push({ ...item });
    });
  };
  loop(array);
  return tileArray;
};

// 解决深拷贝问题
export const deepClone = (obj: any): any => {
  var o: any;
  if (typeof obj == 'object') {
    if (obj === null) {
      o = null;
    } else {
      if (obj instanceof Array) {
        o = [];
        for (var i = 0, len = obj.length; i < len; i++) {
          o.push(deepClone(obj[i]));
        }
      } else {
        o = {};
        for (var j in obj) {
          o[j] = deepClone(obj[j]);
        }
      }
    }
  } else {
    o = obj;
  }
  return o;
};

// 返回随机数 用于非管理页面路由使用
export const getKeyRouter = () => {
  return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
};

// 数组数据转化为 树数据
export const toTree = (data: any) => {
  // 空数组
  let result: any[] = [];
  // 判断不是数组  直接返回
  if (!Array.isArray(data)) {
    return result;
  }
  // 遍历  删除  children 属性  做初始化操作
  data.forEach((item) => {
    delete item.children;
  });
  //  空对象
  let map: any = {};
  data.forEach((item) => {
    map[item.id] = item;
  });

  /**
   * map对象的 键: 是每个id  值：对应的item
   */
  data.forEach((item) => {
    // item.pID 为null时 返回underfined
    let parent = map[item.pID];
    if (parent) {
      (parent.children || (parent.children = [])).push(item);
    } else {
      // 这里push的item是pid为null的数据
      result.push(item);
    }
  });
  return result;
};

// 获取当前年数
export function getYear() {
  var date = new Date();
  var year = date.getFullYear();
  return year;
}

/**
 * @renderRegionText
 * @description 格式化省市县区域
 * @param record
 * @returns string
 */
export const renderRegionText = (record: Record<string, any> | any, paramsList?: string[]) => {
  const provinceName: string = paramsList?.[0] ? paramsList?.[0] : 'provinceCodeName';
  const cityName: string = paramsList?.[1] ? paramsList?.[1] : 'cityCodeName';
  const countyName: string = paramsList?.[2] ? paramsList?.[2] : 'countyCodeName';
  if (record?.[provinceName]) {
    return [record?.[provinceName], record?.[cityName], record?.[countyName]].filter((item) => item).join('/');
  } else {
    return '--';
  }
};

/**
 * 处理省市县初始化回显
 * @param infoObj 数据
 * @param paramsNameList 规定区域字段
 * @returns
 */
export const arieaEchoRender = (infoObj: any, paramsNameList?: string[]) => {
  const provinceID: string = paramsNameList?.[0] ? paramsNameList?.[0] : 'provinceCode';
  const cityID: string = paramsNameList?.[1] ? paramsNameList?.[1] : 'cityCode';
  const countyID: string = paramsNameList?.[2] ? paramsNameList?.[2] : 'countyCode';
  let areaContaNode: any[] = [];
  if (infoObj?.provinceCode) {
    areaContaNode?.push(infoObj?.[provinceID]);
    if (infoObj?.cityCode) {
      areaContaNode?.push(infoObj?.[cityID]);
      if (infoObj?.countyCode) {
        areaContaNode?.push(infoObj?.[countyID]);
      }
    }
  }
  return areaContaNode;
};

/**
 * 处理省市县提交表单方法
 * @param arieaList 数据
 * @param arieaType 区域类型
 * @returns
 */
export const arieaFormSubmit = (arieaList: string[], arieaType?: string[]) => {
  const provinceID: string = arieaType?.[0] ? arieaType?.[0] : 'provinceCode';
  const cityID: string = arieaType?.[1] ? arieaType?.[1] : 'cityCode';
  const countyID: string = arieaType?.[2] ? arieaType?.[2] : 'countyCode';
  return {
    [provinceID]: arieaList?.[0] || null,
    [cityID]: arieaList?.[1] || null,
    [countyID]: arieaList?.[2] || null,
  };
};

/**
 * 返回 被禁用的树 一层一层找父节点id 然后展开
 * @param dataList  平铺 的树数据
 * @param pId   点击当前行  的pid
 * @returns
 */
export const transltateFn = (treeList: any[], rowPid: string) => {
  let idList: string[] = [];
  let handleIdsTree = (dataList: any[], pId: string) => {
    dataList.forEach((item: any) => {
      if (item?.pID) {
        //判断是不是根节点
        if (item.id == pId) {
          idList.push(item.id);
          handleIdsTree(dataList, item.pID);
        }
      } else {
        idList.push(item?.id);
      }
    });
  };
  handleIdsTree(treeList, rowPid);
  let idListRemo: string[] = Array.from(new Set([...idList]));
  return idListRemo;
};

/**
 * 数据字典 如果有颜色处理
 */
export const getColorTextLoadMap = (text: any) => {
  if (text) {
    let [colorText, color] = text?.split('||');
    return {
      color,
      colorText,
    };
  } else {
    let colorText = text;
    return {
      color: '',
      colorText,
    };
  }
};

/**
 * 处理返回变色的DOM 数据字典
 * @param text
 * @returns
 */
export const getColorTextLoadMapDom = (text: any) => {
  if (text) {
    const [colorText, color] = text?.split('||');
    return (
      <span
        style={{
          color: color,
        }}
      >
        {colorText || '--'}
      </span>
    );
  } else {
    return <span>--</span>;
  }
};

// 使用封装的管理页面 组件 获取数据字典数据处理  disabChild:如果有子集，则只能选子集
export const getSelectDataMapList = (selectData: any[], name: any, value: any, disabChild?: boolean) => {
  // 过滤隐藏
  let loopList: any = (dataList: any[]) => {
    return dataList
      ?.filter((item: any) => {
        return item?.isDisplay === 1;
      })
      .map((item: any) => {
        // if (item?.isOpen == 0 || item?.isChoice == 0 || item?.isDisplay == 0) {}
        return {
          ...item,
          name: item?.[`${name}`],
          value: item?.[`${value}`],
          children: item?.children && item?.children?.length > 0 ? loopList(item?.children) : null,
          disabled: disabChild && item?.children?.length > 0 ? true : false,
        };
      });
  };
  let newMaps = loopList(selectData);
  let loops: any = (dataList: any[]) => {
    return dataList?.map((item: any) => {
      // if (item?.isOpen == 0 || item?.isChoice == 0 || item?.isDisplay == 0) {}
      return {
        ...item,
        name: item?.[`${name}`],
        value: item?.[`${value}`],
        children: item?.children && item?.children?.length > 0 ? loops(item?.children) : null,
        disabled: disabChild && item?.children?.length > 0 ? true : false,
      };
    });
  };
  let newMapList = loops(newMaps);
  return newMapList;
};

/**
 * @param textType  0:公司  1:部门   2:岗位  3:用户  4:仓库
 * @returns  返回组织机构图标
 */
export const getDeptPosTreeIcon = (textType: string) => {
  switch (textType) {
    case '0':
      return <MyIcon style={{ marginRight: 5 }} type="icon-bank" />;
    case '1':
      return <MyIcon style={{ marginRight: 5 }} type="icon-cluster" />;
    case '2':
      return <MyIcon style={{ marginRight: 5 }} type="icon-icon_lingdaopishi" />;
    default:
      return <MyIcon style={{ marginRight: 5 }} type="icon-lianxiren" />;
  }
};

/**下载文件公共方法
 * @param url   下载文件接口
 * @param title  下载文件名称
 * @param filePath  下载文件路径
 * @param callback   下载文件回调
 */
export const downloadTemplate = (url: string, title: string, filePath: string, callback: () => void) => {
  let newFilePath = window.encodeURI(filePath);
  const baseUrl = getBaseUrl();

  if (url && title) {
    fetch(resetUrl(baseUrl + url), {
      method: 'GET',
      credentials: 'include',
      headers: new Headers({
        tenantName: getTenant(),
        filePath: newFilePath,
      }),
    }).then((res) => {
      if (res?.ok) {
        res.blob().then((blob) => {
          if (blob.size == 0) {
            message.error('下载出错！');
            // setDownLoading(false);
            callback();
            return;
          }
          let link = document.createElement('a');
          link.href = window.URL.createObjectURL(blob);
          link.download = title;
          document.body.appendChild(link);
          link.click();
          window.URL.revokeObjectURL(link.href);
          document.body.removeChild(link);
          // setDownLoading(false);
        });
      } else {
        notification.error({
          message: RequestCodeMessage?.[res.status],
        });
      }
      // setDownLoading(false);
      callback();
    });
  } else {
    // setDownLoading(false);
    callback();
    message.error('暂无文件路径或文件标题');
  }
};

/**下载文件公共方法  Post */
export const downloadTemplatePost = (url: string, title: string, filePath: string, callback: () => void, method?: string) => {
  let newFilePath = window.encodeURI(filePath);
  let baseUrl = getBaseUrl();
  let headerParams: Record<string, any> = {
    tenantName: getTenant(),
  };

  /**外层传了POST 资源加在请求体中， 默认是GET，资源加在请求头中 */
  if (method) {
    headerParams['Content-Type'] = 'application/json';
  }
  // let baseUrl = 'http://192.168.153.192:31019'; //振豪本地
  if (url && title) {
    fetch(resetUrl(baseUrl + url), {
      method: method ?? 'GET',
      credentials: 'include',
      headers: new Headers({ ...headerParams }),
      body: JSON.stringify({
        filePath: newFilePath,
      }),
    }).then((res) => {
      if (res?.ok) {
        res.blob().then((blob) => {
          if (blob.size == 0) {
            message.error('下载出错！');
            // setDownLoading(false);
            callback();
            return;
          }
          let link = document.createElement('a');
          link.href = window.URL.createObjectURL(blob);
          link.download = title;
          document.body.appendChild(link);
          link.click();
          window.URL.revokeObjectURL(link.href);
          document.body.removeChild(link);
          // setDownLoading(false);
        });
      } else {
        notification.error({
          message: RequestCodeMessage?.[res.status],
        });
      }
      // setDownLoading(false);
      callback();
    });
  } else {
    // setDownLoading(false);
    callback();
    message.error('暂无文件路径或文件标题');
  }
};

/**
 * 调用打印预览 PDF
 * @param url pdf 地址
 */
export const printerPDF = (url: string) => {
  let printerUrl = getPrinterUrl();
  fetch(printerUrl + url)
    .then((response) => response.blob())
    .then((text) => {
      const blob = new Blob([text], { type: 'application/pdf' });
      const blobUrl = URL.createObjectURL(blob);
      let printWindow: any = window.open(blobUrl, '_blank');
      printWindow.print();
      URL.revokeObjectURL(blobUrl);
    })
    .catch((error) => console.error('打印失败:', error));
};

/**处理 公共管理组件 下拉框 数据 ,返回 {value: '', name: ''}
 * @param selectData  数据源
 * @param name   展示名字
 * @param value   选中 id
 * @returns
 */
export const getSelectDataCommon = (selectData: any[], name: any, value: any) => {
  let newData = selectData?.map((item) => {
    return {
      name: item?.[`${name}`],
      value: item?.[`${value}`],
    };
  });
  return newData;
};

export const fixedZero = (val: any) => {
  return val * 1 < 10 ? `0${val}` : val;
};

/**
 * 获取今天,本周, 本月,本年开始时间 结束时间
 * @param type  today: 今天  week:本周  month:本月  year:本年    oneYear:去年今天到现在    threeYear:三年前今天到现在
 * @returns
 */
export const getTimeDistance = (type: string) => {
  const now = new Date();
  const oneDay = 1000 * 60 * 60 * 24;

  if (type === 'today') {
    now.setHours(0);
    now.setMinutes(0);
    now.setSeconds(0);
    return [moment(now), moment(now.getTime() + (oneDay - 1000))];
  }

  if (type === 'week') {
    let day = now.getDay();
    now.setHours(0);
    now.setMinutes(0);
    now.setSeconds(0);

    if (day === 0) {
      day = 6;
    } else {
      day -= 1;
    }

    const beginTime = now.getTime() - day * oneDay;

    return [moment(beginTime), moment(beginTime + (7 * oneDay - 1000))];
  }

  if (type === 'month') {
    const year = now.getFullYear();
    const month = now.getMonth();
    const nextDate = moment(now).add(1, 'months');
    const nextYear = nextDate.year();
    const nextMonth = nextDate.month();

    return [moment(`${year}-${fixedZero(month + 1)}-01 00:00:00`), moment(moment(`${nextYear}-${fixedZero(nextMonth + 1)}-01 00:00:00`).valueOf() - 1000)];
  }

  if (type === 'year') {
    const year = now.getFullYear();

    return [moment(`${year}-01-01 00:00:00`), moment(`${year}-12-31 23:59:59`)];
  }

  if (type === 'oneYear') {
    const year = now.getFullYear();
    const month = now.getMonth();
    const nowData = moment(now.getTime()).format('YYYY-MM-DD');
    const oldYearDay = moment(now.getTime()).format('MM-DD'); // 08-27
    return [moment(`${year - 1}-${oldYearDay} `), moment(`${nowData} 23:59:59`)];
  }

  if (type === 'threeYear') {
    const year = now.getFullYear();
    const month = now.getMonth();
    const nowData = moment(now.getTime()).format('YYYY-MM-DD');
    const oldYearDay = moment(now.getTime()).format('MM-DD'); // 08-27
    return [moment(`${year - 3}-${oldYearDay} `), moment(`${nowData} 23:59:59`)];
  }
};

/**
 * 随机生成颜色
 */
export const randomHexColor = () => {
  //随机生成十六进制颜色
  var hex = Math.floor(Math.random() * 16777216).toString(16);
  //生成ffffff以内16进制数
  while (hex.length < 6) {
    //while循环判断hex位数，少于6位前面加0凑够6位
    hex = '0' + hex;
  }
  return '#' + hex; //返回‘#'开头16进制颜色
};

/**
 * 合并单元格操作
 * @param data 全部Data列表数据
 * @param param 用于相同字段合并的key
 * @param value 展示的文本值(支持text或reactNode)
 * @param row 当前行的数据 record
 * @param index 当前行的索引index
 * @returns 示例参照 短信统计
 */
export const mergeCells = (data: any, param: any, value: any, row: any, index: number) => {
  const { colorText, color } = getColorTextLoadMap(value);
  value = (
    <>
      <span className={pageStyles['over-flow-hidden']} style={{ color }}>
        {colorText}
      </span>
    </>
  );

  const obj: any = {
    children: value === '' || value === undefined || value === null ? '--' : value,
    props: {
      rowSpan: 0,
    },
  };
  let groupList: any = [];
  let key = '';
  let flag = true; // 控制数据相邻重复问题
  if (Array.isArray(param)) {
    // 多个条件
    groupList = groupBy(
      data.filter((item: any) => item[param[0]] === row[param[0]]),
      param[1],
    );
    // eslint-disable-next-line prefer-destructuring
    key = param[1];
    flag = data[index + groupList[row[key]].length - 1] && row[param[0]] === data[index + groupList[row[key]]?.length - 1][param[0]];
  } else {
    // 只有一个条件
    // 数据分组
    groupList = groupBy(data, param);
    key = param;
    // 判断边界
  }
  if (data[index + groupList[row[key]].length - 1] && row[key] === data[index + groupList[row[key]].length - 1][key] && flag) {
    obj.props.rowSpan = groupList[row[key]].length;
  } else {
    obj.props.rowSpan = 0;
  }
  return obj;
};

/**
 * @export
 * @param {*} att 拼接的文件地址（多个文件用||分割的）
 * return 返回分割之后的数组
 */
export const splitFileUrl = (att: string) => {
  let attArr = att?.split('||');
  let attList: any[] = [];
  let arr: any = [];
  if (attArr?.length > 0) {
    attArr.map((e, i) => {
      arr = e?.split('/');
      attList[i] = {
        attachName: arr[arr.length - 1],
        attachUrl: attArr[i],
      };
    });
  }
  return attList;
};

/**
 * 处理超过多少字的tooltip
 */
export const tooltipLength = (str: string | null, num: number) => {
  let newStr: any = str;
  if (str && str?.length > num) {
    newStr = str.substring(0, num) + '...';
  }
  return newStr;
};

/**
 * 具体在详情有文件的时候使用
 * 返回文件名称处理
 * @param fileName 文件对象
 * @returns
 */
export const getFileNameNotType = (fileName: any, nameLength: number) => {
  let arr: string[] = fileName?.split('.');
  let endType: any = arr?.pop();
  let nameStr: string = arr.join('');
  if (nameStr.length >= nameLength) {
    nameStr = nameStr.substring(0, nameLength - 3) + '...' + nameStr.slice(-(nameLength - (nameLength - 3)));
  }
  return nameStr + `.${endType}`;
};

/**
 * 具体在详情有文件的时候使用
 * 返回文件名称处理
 * @param fileName 文件对象
 * @returns
 */
export const newGetFileNameNotType = (fileName: any, nameLength: number) => {
  let arr: string[] = fileName?.split('.');
  let endType: any = arr?.pop();
  let nameStr: string = arr.join('');
  const nameList: string[] = nameStr?.split('/');
  let fieldName: string = nameList?.[nameList?.length - 1];
  if (fieldName.length >= nameLength) {
    fieldName = fieldName.substring(0, nameLength - 3) + '...' + fieldName.slice(-(nameLength - (nameLength - 3)));
  }
  return fieldName + `.${endType}`;
};

/**处理树选中后获取用户的参数
 * @param list 传入的选中书id
 * @returns
 */
export const commonDeptGetUser = (list: any[]) => {
  let paramsIDS: any = []; //参数保存
  let checkRow: any = list[0]; //点击选中的节点

  // 递归树
  let loop = (treeData: any[]) => {
    treeData?.forEach((item: any) => {
      if (item?.children && item?.children?.length > 0) {
        loop(item?.children);
      }
      if (checkRow?.textType == item?.textType) {
        paramsIDS?.push(item?.id);
      }
    });
  };
  loop(list);
  let idsString = paramsIDS?.join('|');
  if (checkRow?.textType == 0) {
    return { userCompanyID: idsString };
  } else if (checkRow?.textType == 1) {
    return { userDepartmentID: idsString };
  } else if (checkRow?.textType == 2) {
    return { userPositionID: idsString };
  }
};

/**
 * 数组根据对象某一个属性如果有重复值,去重
 * @param arrList
 * @param key
 * @returns
 */
export const uniqueArray = (arrList: Record<string, any>[], key: string) => {
  const res = new Map();
  return arrList.filter((item: any) => !res.has(item?.[key]) && res.set(item?.[key], 1));
};

/**
 * 公共滚动定位
 */
export const clickScrollToAnchor = (id: string, scrollObj?: any) => {
  if (id) {
    let anchorElement = document.getElementById(id);
    anchorElement?.scrollIntoView(
      scrollObj
        ? scrollObj
        : {
            behavior: 'smooth',
            block: 'start',
            inline: 'nearest',
          },
    );
  }
};

/**
 * 随机生成相关业务编号
 * @keyWord 业务前缀
 * @myyear 年
 * @mymonth 月
 * @myweekday 日
 * @number  5位随机数字
 */
export const businessCodeKeys = (key: string) => {
  let keyWord = key;
  let date = new Date();
  let myyear: any = date.getFullYear();
  let mymonth: any = date.getMonth() + 1;
  let myweekday: any = date.getDate();
  let number: number = parseInt((Math.random() * 100000) as any);
  mymonth < 10 ? (mymonth = '0' + mymonth) : mymonth;
  myweekday < 10 ? (myweekday = '0' + myweekday) : myweekday;

  return `${keyWord}${myyear}${mymonth}${myweekday}${number}`;
};

/**
 * 刷新页面存储当前页面路由数据
 */
export const encrySessionStorage = (encryData: Record<string, any> | any) => {
  let secretKey: string = 'workPC&SecretKey';
  let iv: string = 'workPC&RouerIvZL';
  let encryParams: any = null;
  if (encryData) {
    if (typeof encryData == 'string') {
      encryParams = encryData ? EncryptIv(encryData, secretKey, iv) : ''; //加密参数
    } else {
      let encryDataStr: string = JSON.stringify(encryData);
      encryParams = encryData ? EncryptIv(encryDataStr, secretKey, iv) : ''; //加密参数
    }
  }
  return encryParams;
};

/**
 * 补零函数
 * @num 需要补零的数字
 * @length 需要补齐的长度
 * @returns
 */
export function padStart(num: number, length: number) {
  return (Array(length).join('0') + num).slice(-length);
}

/**
 * 路由参数解密方法
 * @returns
 */
export const decrySessionStorage = (decryStr: string | any) => {
  const secretKey: string = 'workPC&SecretKey';
  const iv: string = 'workPC&RouerIvZL';
  let decryParams: any = null;
  if (decryStr) {
    decryParams = DecryptIv(decryStr, secretKey, iv);
  }
  return decryParams;
};

/**已知文件路径，获取文件名xxx.doc */
export const getFileNameByPath = (path: any) => {
  let index = path?.lastIndexOf('/'); // lastIndexOf("/")  找到最后一个  /  的位置
  let fileName = path?.substr(index + 1); // substr() 截取剩余的字符，即得文件名xxx.doc
  return fileName;
};

/**已知文件路径，获取文件类型doc */
export const getFileTypeByPath = (path: any) => {
  let index = path?.lastIndexOf('.'); // lastIndexOf("/")  找到最后一个  /  的位置
  let fileType = path?.substr(index + 1); // substr() 截取剩余的字符，即文件名doc
  return fileType;
};

/**
 * 处理搜索变色
 * @param text //整体名称
 * @param searchText 搜索内容
 * @param endDom //名称后面拼接
 * @returns
 */
export const searchChangeColor = (text: string, searchText: string, endDom: string | any = '') => {
  const newSearchText: string = searchText ? searchText : '';
  const nameLength = text?.length;
  const select = text?.search(newSearchText);
  const searchLength = newSearchText?.length;
  const afterStr = text?.slice(0, select);
  const selectStr = newSearchText;
  const beforeStr = text?.slice(select + searchLength, nameLength);
  const titleTree =
    select > -1 && selectStr ? (
      <div className={pageStyles['over-flow-hidden']}>
        <span>{afterStr}</span>
        <span style={{ color: '#f50' }}>{selectStr}</span>
        <span>{beforeStr}</span>
        {endDom}
      </div>
    ) : (
      <span className={pageStyles['over-flow-hidden']}>{`${text}${endDom}`}</span>
    );
  return titleTree;
};

/**
 * 获取数据字典
 * @param loadParams 获取的数据字典前八位 数组
 * @param isManual 自否手动触发
 * @returns
 */
export const getLoadMapList = (loadParams: string[], isManual = false) => {
  //获取数据字典loadMdicMap
  const loadMdicMapList = useRequest(
    () => {
      return loadMdicMap(loadParams);
    },
    {
      manual: isManual,
    },
  );

  // 数据字典数据
  let loadMapInfo = useMemo(() => {
    if (loadMdicMapList?.data?.msgFlag) {
      let newLoadMap: Record<string, any> = { ...loadMdicMapList?.data?.obj };
      Object.keys(loadMdicMapList?.data?.obj)?.forEach((item: any) => {
        newLoadMap[item] = newLoadMap[item]?.filter((cItem: any) => cItem?.isDisplay == '1');
      });
      return newLoadMap;
    } else {
      return {};
    }
  }, [loadMdicMapList?.data]);

  return {
    loadMapInfo,
    mapLoading: loadMdicMapList?.loading,
    mapLoadRun: loadMdicMapList?.run,
  };
};

/**
 * 处理获取组织机构 岗位参数
 */
export const handDeptAndPostParams = (queryInfo: Record<string, any>) => {
  let requestParams: Record<string, any> = {
    params: queryInfo?.params,
    flowType: queryInfo?.flowType,
  };
  if (queryInfo?.flowType == 'null') {
    if (queryInfo?.params == '0') {
      requestParams['flowType'] = 'null';
      requestParams['orgID'] = getCompanyID();
    } else if (queryInfo?.params == '1') {
      requestParams['orgID'] = getUserDepID();
    } else if (queryInfo?.params == '2') {
      requestParams['orgID'] = getPosIDs();
    }
  } else {
    requestParams['orgID'] = getPosIDs();
  }
  return requestParams;
};

/**
 * 处理审批管理页 attributes 参数方法
 * @param defaultList  业务默认 搜索 Cloumns 配置
 * @param searchParams  传入接口中的 参数数据
 * @param tableTitle 表名
 * @returns
 *
 * @fieldName :字段名称
 * @fieldType ：字段类型
 * @fieldParam ： 0:普通 1:字典 2:人 3:岗 4:部门 5:公司 6:行政区域
 * @isSearch ：是否有搜索值 0否 1是
 * @fieldUse ：是否数据库字段 0是 1否
 * @searchType ：是否模糊搜索  0模糊 1精确
 * @valueInfo ：搜索值
 */
export const handleCheckSearchParams = (defaultList: Record<string, any>[], searchParams: Record<string, any>, tableTitle: string) => {
  let changeSearchList: Record<string, any>[] = []; // 存储工作流修改后的搜索参数
  let searchValues: Record<string, any> = { ...searchParams }; //存储传入接口的搜索参数,用于清除外层字段

  defaultList?.forEach((item: any) => {
    let newItem: Record<string, any> = {
      ...item,
      fieldUse: 0,
      isSearch: 0,
    };

    if (item?.fieldType == 'Date') {
      let isHaveDate: boolean = false; //判断是否有时间参数，有放入 start,end 删除 time  没有相反
      if (!!searchParams?.[`${item?.fieldName}Start`]) {
        let startTimeInfo = {
          ...item,
          fieldName: `${item?.fieldName}Start`,
          fieldParam: 0,
          fieldType: 'Date',
          searchType: 0, // 是否模糊  0 模糊   1精确
          fieldUse: 0, //是否是数据库字段  0 是, 1 否
          isSearch: 1, //是否有搜索值  0否  1是
          valueInfo: searchParams?.[`${item?.fieldName}Start`],
        };
        changeSearchList?.push(startTimeInfo);
        isHaveDate = true;
      }
      if (!!searchParams?.[`${item?.fieldName}End`]) {
        let endTimeInfo = {
          ...item,
          fieldName: `${item?.fieldName}End`,
          fieldParam: 0,
          fieldType: 'Date',
          searchType: 0,
          fieldUse: 0,
          isSearch: 1,
          valueInfo: searchParams?.[`${item?.fieldName}End`],
        };
        changeSearchList?.push(endTimeInfo);
        isHaveDate = true;
      }
      delete searchValues?.[`${item?.fieldName}Start`];
      delete searchValues?.[`${item?.fieldName}End`];

      if (!isHaveDate) {
        changeSearchList?.push(item);
      }
    } else if (item?.fieldType == 'BigDecimal') {
      //数值范围
      let isHaveRanage: boolean = false; //判断是否有时间参数，有放入 Max,Min 删除 time  没有相反

      if (!!searchParams?.[`${item?.fieldName}Min`]) {
        const fileParameMin: string = searchParams?.[`${item?.fieldName}Min`];
        const newFileParameMin = fileParameMin?.includes('.') ? fileParameMin : `${fileParameMin}.0001`;
        const ranMin: Record<string, any> = {
          ...item,
          fieldName: `${item?.fieldName}Min`,
          searchType: 0, // 是否模糊  0 模糊   1精确
          fieldUse: 0, //是否是数据字段  0 是, 1 否
          isSearch: 1,
          valueInfo: Number(newFileParameMin),
        };
        delete searchValues?.[`${item?.fieldName}Min`];
        changeSearchList?.push(ranMin);
        isHaveRanage = true;
      }
      if (!!searchParams?.[`${item?.fieldName}Max`]) {
        const fileParameMax: string = searchParams?.[`${item?.fieldName}Max`];
        const newFileParameMax = fileParameMax?.includes('.') ? fileParameMax : `${fileParameMax}.0001`;
        const ranMax: Record<string, any> = {
          ...item,
          fieldName: `${item?.fieldName}Max`,
          searchType: 0, // 是否模糊  0 模糊   1精确
          fieldUse: 0, //是否是数据字段  0 是, 1 否
          isSearch: 1,
          valueInfo: Number(newFileParameMax),
        };
        delete searchValues?.[`${item?.fieldName}Max`];
        changeSearchList?.push(ranMax);
        isHaveRanage = true;
      }

      if (!isHaveRanage) {
        changeSearchList?.push(item);
      }
    } else {
      if (!!searchParams?.[item?.fieldName]) {
        newItem = {
          ...item,
          fieldUse: 0,
          isSearch: 1,
          valueInfo: item?.fieldType == 'Integer' ? Number(searchParams?.[item?.fieldName]) : searchParams?.[item?.fieldName],
        };
      }
      delete searchValues?.[item?.fieldName];
      changeSearchList?.push(newItem);
    }
  });

  const searchPayload: Record<string, any> = {
    attributes: {
      [tableTitle]: changeSearchList,
      // ...timeInfo,
    },
    ...searchValues,
  };
  return searchPayload;
};

/**
 * 处理管理页面 搜索参数公共方法
 * @param configColumns 搜索参数配置
 * @param searchInfo 传入接口中的搜索值
 * @param tableName 业务表名
 * @param transInfo 翻译字段
 *
 * @fieldName :字段名称
 * @fieldType ：字段类型
 * @fieldParam ： 0:普通 1:字典 2:人 3:岗 4:部门 5:公司 6:行政区域
 * @isSearch ：是否有搜索值 0否 1是
 * @fieldUse ：是否数据库字段 0是 1否
 * @searchType ：是否模糊搜索  0模糊 1精确
 * @valueInfo ：搜索值
 */
export const commonManageSearchParams = (configColumns: Record<string, any>[], searchInfo: Record<string, any>, transInfo?: Record<string, any>) => {
  let newSearchList: Record<string, any>[] = [];
  let searchValues: Record<string, any> = { ...searchInfo };

  configColumns?.forEach((item: any) => {
    const searchParams: Record<string, any> = {
      ...item?.searchParams,
      fieldName: item?.name,
    };

    if (searchParams?.fieldType == 'DeptUserType') {
      if (!!searchInfo?.[`${searchParams?.fieldInfo?.[0]}`]) {
        const compayName: string = searchParams?.fieldInfo?.[0];
        const compayField: number = searchParams?.fieldParam?.[0];
        const compayItem: Record<string, any> = {
          fieldName: compayName,
          isSearch: 1,
          valueInfo: searchInfo?.[compayName],
          fieldType: 'String',
          fieldParam: compayField,
          fieldUse: searchParams?.fieldUse,
          searchType: searchParams?.searchType,
          seq: searchParams?.seq,
        };
        newSearchList?.push(compayItem);
        delete searchValues?.[compayName];
      }

      if (!!searchInfo?.[`${searchParams?.fieldInfo?.[1]}`]) {
        const deptName: string = searchParams?.fieldInfo?.[1];
        const deptField: number = searchParams?.fieldParam?.[1];
        const deptItem: Record<string, any> = {
          fieldName: deptName,
          isSearch: 1,
          valueInfo: searchInfo?.[deptName],
          fieldType: 'String',
          fieldParam: deptField,
          fieldUse: searchParams?.fieldUse,
          searchType: searchParams?.searchType,
          seq: searchParams?.seq,
        };
        newSearchList?.push(deptItem);
        delete searchValues?.[deptName];
      }

      if (!!searchInfo?.[`${searchParams?.fieldInfo?.[2]}`]) {
        const postitonName: string = searchParams?.fieldInfo?.[2];
        const postitonField: number = searchParams?.fieldParam?.[2];
        const postitonItem: Record<string, any> = {
          fieldName: postitonName,
          isSearch: 1,
          valueInfo: searchInfo?.[postitonName],
          fieldType: 'String',
          fieldParam: postitonField,
          fieldUse: searchParams?.fieldUse,
          searchType: searchParams?.searchType,
          seq: searchParams?.seq,
        };
        newSearchList?.push(postitonItem);
        delete searchValues?.[postitonName];
      }

      if (!!searchInfo?.[`${searchParams?.fieldInfo?.[3]}`]) {
        const userName: string = searchParams?.fieldInfo?.[3];
        const userField: number = searchParams?.fieldParam?.[3];
        const userItem: Record<string, any> = {
          fieldName: userName,
          isSearch: 1,
          valueInfo: searchInfo?.[userName],
          fieldType: 'String',
          fieldParam: userField,
          fieldUse: searchParams?.fieldUse,
          searchType: searchParams?.searchType,
          seq: searchParams?.seq,
        };
        newSearchList?.push(userItem);
        delete searchValues?.[userName];
      }
    } else if (searchParams?.fieldType == 'AreaType') {
      if (!!searchInfo?.[`${searchParams?.fieldInfo?.[0]}`]) {
        const provinceName: string = searchParams?.fieldInfo?.[0];
        const provinceItem: Record<string, any> = {
          fieldName: provinceName,
          isSearch: 1,
          valueInfo: searchInfo?.[provinceName],
          fieldType: 'String',
          fieldParam: searchParams?.fieldParam,
          fieldUse: searchParams?.fieldUse,
          searchType: searchParams?.searchType,
          seq: searchParams?.seq,
        };
        newSearchList?.push(provinceItem);
        delete searchValues?.[provinceName];
      }

      if (!!searchInfo?.[`${searchParams?.fieldInfo?.[1]}`]) {
        const cityName: string = searchParams?.fieldInfo?.[1];
        const cityItem: Record<string, any> = {
          fieldName: cityName,
          isSearch: 1,
          valueInfo: searchInfo?.[cityName],
          fieldType: 'String',
          fieldParam: searchParams?.fieldParam,
          fieldUse: searchParams?.fieldUse,
          searchType: searchParams?.searchType,
          seq: searchParams?.seq,
        };
        newSearchList?.push(cityItem);
        delete searchValues?.[cityName];
      }

      if (!!searchInfo?.[`${searchParams?.fieldInfo?.[2]}`]) {
        const countyName: string = searchParams?.fieldInfo?.[2];
        const countyItem: Record<string, any> = {
          fieldName: countyName,
          isSearch: 1,
          valueInfo: searchInfo?.[countyName],
          fieldType: 'String',
          fieldParam: searchParams?.fieldParam,
          fieldUse: searchParams?.fieldUse,
          searchType: searchParams?.searchType,
          seq: searchParams?.seq,
        };
        newSearchList?.push(countyItem);
        delete searchValues?.[countyName];
      }
    } else if (searchParams?.fieldType == 'DateRange') {
      if (!!searchInfo?.[`${searchParams?.rangeName?.[0]}`]) {
        const startTimeInfo: Record<string, any> = {
          fieldName: `${searchParams?.rangeName?.[0]}`,
          isSearch: 1,
          valueInfo: searchInfo?.[`${searchParams?.rangeName?.[0]}`],
          fieldType: searchParams?.fieldType,
          fieldParam: searchParams?.fieldParam,
          fieldUse: searchParams?.fieldUse,
          searchType: searchParams?.searchType,
          seq: searchParams?.seq,
        };
        newSearchList?.push(startTimeInfo);
        delete searchValues?.[`${searchParams?.rangeName?.[0]}`];
      }
      if (!!searchInfo?.[`${searchParams?.rangeName?.[1]}`]) {
        const endTimeInfo: Record<string, any> = {
          fieldName: `${searchParams?.rangeName?.[1]}`,
          isSearch: 1,
          valueInfo: searchInfo?.[`${searchParams?.rangeName?.[1]}`],
          fieldType: searchParams?.fieldType,
          fieldParam: searchParams?.fieldParam,
          fieldUse: searchParams?.fieldUse,
          searchType: searchParams?.searchType,
          seq: searchParams?.seq,
        };
        newSearchList?.push(endTimeInfo);
        delete searchValues?.[`${searchParams?.rangeName?.[1]}`];
      }
    } else if (searchParams?.fieldType == 'Date') {
      if (!!searchInfo?.[`${searchParams?.fieldName}Start`]) {
        const startTimeInfo: Record<string, any> = {
          fieldName: `${searchParams?.fieldName}Start`,
          isSearch: 1,
          valueInfo: searchInfo?.[`${searchParams?.fieldName}Start`],
          fieldType: searchParams?.fieldType,
          fieldParam: searchParams?.fieldParam,
          fieldUse: searchParams?.fieldUse,
          searchType: searchParams?.searchType,
          seq: searchParams?.seq,
        };
        newSearchList?.push(startTimeInfo);
        delete searchValues?.[`${searchParams?.fieldName}Start`];
      }
      if (!!searchInfo?.[`${searchParams?.fieldName}End`]) {
        const endTimeInfo: Record<string, any> = {
          fieldName: `${searchParams?.fieldName}End`,
          isSearch: 1,
          valueInfo: searchInfo?.[`${searchParams?.fieldName}End`],
          fieldType: searchParams?.fieldType,
          fieldParam: searchParams?.fieldParam,
          fieldUse: searchParams?.fieldUse,
          searchType: searchParams?.searchType,
          seq: searchParams?.seq,
        };
        newSearchList?.push(endTimeInfo);
        delete searchValues?.[`${searchParams?.fieldName}End`];
      }
    } else if (searchParams?.fieldType == 'BigDecimal') {
      if (!!searchInfo?.[`${searchParams?.fieldName}Min`]) {
        const fileParameMin: string = searchInfo?.[`${searchParams?.fieldName}Min`];
        const newFileParameMin = fileParameMin?.includes('.') ? fileParameMin : `${fileParameMin}.0001`;
        const ranMin: Record<string, any> = {
          fieldName: `${searchParams?.fieldName}Min`,
          isSearch: 1,
          valueInfo: Number(newFileParameMin),
          fieldType: searchParams?.fieldType,
          fieldParam: searchParams?.fieldParam,
          fieldUse: searchParams?.fieldUse,
          searchType: searchParams?.searchType,
          seq: searchParams?.seq,
        };
        newSearchList?.push(ranMin);
        delete searchValues?.[`${searchParams?.fieldName}Min`];
      }
      if (!!searchInfo?.[`${searchParams?.fieldName}Max`]) {
        const fileParameMax: string = searchInfo?.[`${searchParams?.fieldName}Max`];
        const newFileParameMax = fileParameMax?.includes('.') ? fileParameMax : `${fileParameMax}.0001`;
        const ranMax: Record<string, any> = {
          fieldName: `${searchParams?.fieldName}Max`,
          isSearch: 1,
          valueInfo: Number(newFileParameMax),
          fieldType: searchParams?.fieldType,
          fieldParam: searchParams?.fieldParam,
          fieldUse: searchParams?.fieldUse,
          searchType: searchParams?.searchType,
          seq: searchParams?.seq,
        };
        newSearchList?.push(ranMax);
        delete searchValues?.[`${searchParams?.fieldName}Max`];
      }
    } else {
      if (!!searchInfo?.[searchParams?.fieldName] || searchInfo?.[searchParams?.fieldName] == 0) {
        const otherItem: Record<string, any> = {
          fieldName: searchParams?.fieldName,
          isSearch: 1,
          valueInfo: searchParams?.fieldType == 'Integer' ? Number(searchInfo?.[searchParams?.fieldName]) : searchInfo?.[searchParams?.fieldName],
          fieldType: searchParams?.fieldType,
          fieldParam: searchParams?.fieldParam,
          fieldUse: searchParams?.fieldUse,
          searchType: searchParams?.searchType,
          seq: searchParams?.seq,
        };
        newSearchList?.push(otherItem);
        delete searchValues?.[searchParams?.fieldName];
      }
    }
  });

  const translateObj: Record<string, any> = {
    ...transInfo,
    areaFlag: transInfo?.areaTransName ? true : false,
  };

  return {
    // businessMap: {
    //   [tableName]: newSearchList,
    // },
    ...translateObj,
    ...searchValues,
    whereParams: newSearchList,
  };
};

/** 添加按钮鼠标移出后,不选中 */
export const onMouseOutBtn = (event: any) => {
  event?.target?.nodeName == 'BUTTON' ? event?.target?.blur() : event.target.parentNode.blur();
};

/** 公共关闭弹框方法 */
export const onCloseModalCommon = (modalRef: any) => {
  if (modalRef) {
    if (modalRef?.current) {
      if (modalRef?.current.onModalCancel) {
        modalRef?.current?.onModalCancel();
      }
    }
  }
};

/** 图片容错地址 */
export const imageFallbackStr: string =
  '';

/** 按钮字体小 */
export const btntTxtStyle: React.CSSProperties = {
  fontSize: '.75rem',
};

/** 处理详情页面展示文件下载 */
export const fileDownloadDetail = (fileUrl: string, fileRequest: string, colSpan?: number) => {
  const fileList: Record<string, any>[] = splitFileUrl(fileUrl);
  if (fileList?.length > 0) {
    return (
      <Row gutter={[8, 8]}>
        {fileList?.map((e: any, i: number) => {
          return (
            <Col span={colSpan || 24} key={`${i}-file`}>
              <Tooltip title={e.attachName}>
                <a
                  onClick={() => {
                    message.success('下载中，请稍后...');
                    downloadTemplate(fileRequest, e?.attachName, e?.attachUrl, () => {});
                  }}
                >
                  <MyIcon type="icon-file-text-fill" />
                  &nbsp;
                  {getFileNameNotType(e.attachName, 8)}
                </a>
              </Tooltip>
            </Col>
          );
        })}
      </Row>
    );
  } else {
    return '--';
  }
};

/**
 * 处理修改记录逻辑
 * @param paramsList [ code:表单字段， name：表单字段名称]
 * @param newInfo 表单新输入的值
 * @param oldInfo 之前已经存入的旧值
 * @returns
 */
export const modifyChangeRecord = (paramsList: Record<string, any>[], newInfo: Record<string, any>, oldInfo: Record<string, any>) => {
  let modifyJson: Record<string, any>[] = [];
  paramsList?.forEach((item: any) => {
    if (newInfo?.[item?.code] && newInfo?.[item?.code] != oldInfo?.[item?.code]) {
      modifyJson?.push({
        fieldName: item?.name,
        oldValue: oldInfo?.[item?.code],
        newValue: newInfo?.[item?.code],
        id: `${getKeyRouter()}${getKeyRouter()}${getKeyRouter()}`,
      });
    }
  });
  return modifyJson;
};

/**
 * 处理修改记录 获取字典名称和颜色
 * @param loadList 字典数据
 * @param checkCode 改变的值
 * @returns
 */
export const getChangeLoadMapColorText = (loadList: Record<string, any>, loadEnumCode: string, checkCode: string | string[]) => {
  const checkObj: Record<string, any> = loadList?.[`${getTenantID()}${loadEnumCode}`]?.filter((item: any) => {
    return checkCode?.includes(item?.id);
  });
  let checkStrAll: string[] = [];
  checkObj?.forEach((item: any) => {
    checkStrAll?.push(item?.name);
  });
  // return `${checkObj?.name}||${checkObj?.fontColor}`;
  return checkStrAll?.toString();
};

/** 表格排序 */
export const tableSorter = (a: Record<string, any>, b: any, fieldName: string) => {
  return a?.[fieldName] < b?.[fieldName] ? -1 : 1;
};

/**
 * @param text 值
 * @param isShowTooltip 是否溢出隐藏并且加Tooltip
 * @returns
 */
export const renderTableText = (text: string | number | null, isShowTooltip = false, toolLength = 100) => {
  const index = ['0', '1'].indexOf(String(text) || '');
  // 干掉字典颜色
  const { colorText, color } = getColorTextLoadMap(String(text));
  const info = {
    word: colorText == 'undefined' || colorText == 'null' || !colorText ? '--' : colorText,
    color: color,
  };

  if (index != -1) {
    info.word = index == 1 ? '是' : '否';
    info.color = index == 1 ? '#409eff' : 'red';
  }

  if (isShowTooltip && info.word != '--') {
    return (
      <Tooltip title={tooltipLength(info.word, toolLength)}>
        <span className={pageStyles['over-flow-hidden']} style={{ color: info.color }}>
          {info.word || '--'}
        </span>
      </Tooltip>
    );
  } else {
    return <span style={{ color: info.color }}>{info.word || '--'}</span>;
  }
};

/**
 * @param text 值
 * @param isShowTooltip 是否溢出隐藏并且加Tooltip
 * @returns
 */
export const renderTableTextNotColor = (text: string | number | null, isShowTooltip = false, toolLength = 100) => {
  const index = ['0', '1'].indexOf(String(text) || '');
  // 干掉字典颜色
  const { colorText } = getColorTextLoadMap(String(text));
  const info = {
    word: colorText == 'undefined' || colorText == 'null' || !colorText ? '--' : colorText,
  };

  if (index != -1) {
    info.word = index == 1 ? '是' : '否';
  }

  if (isShowTooltip && info.word != '--') {
    return (
      <Tooltip title={tooltipLength(info.word, toolLength)}>
        <span className={pageStyles['over-flow-hidden']}>{info.word || '--'}</span>
      </Tooltip>
    );
  } else {
    return <span>{info.word || '--'}</span>;
  }
};

/**
 * @param text 值
 * @param isShowTooltip 是否溢出隐藏并且加Tooltip
 * @returns
 */
export const renderDetailText = (text: string | number | null, isShowTooltip = false, toolLength = 100) => {
  const index = ['0', '1'].indexOf(String(text) || '');
  // 干掉字典颜色
  const { colorText, color } = getColorTextLoadMap(String(text));
  const info = {
    word: colorText == 'undefined' || colorText == 'null' || !colorText ? '--' : colorText,
    color: color,
  };

  if (index != -1) {
    info.word = index == 1 ? '是' : '否';
    info.color = index == 1 ? '#409eff' : 'red';
  }

  if (isShowTooltip && info.word != '--') {
    return (
      <Tooltip title={tooltipLength(info.word, toolLength)}>
        <span style={{ color: info.color, wordBreak: 'break-all' }}>{info.word || '--'}</span>
      </Tooltip>
    );
  } else {
    return <span style={{ color: info.color, wordBreak: 'break-all' }}>{info.word || '--'}</span>;
  }
};

interface IUpdateDetailRightSwitch {
  status: string;
  value: number;
  max: number;
  min?: number;
}
/** 业务右侧数据切换 */
export const updateDetailRightSwitch = ({ status, value, max, min = 1 }: IUpdateDetailRightSwitch): number => {
  let result = value;
  switch (status) {
    case 'next':
      result = value == max ? min : value + 1;
      break;
    case 'prev':
      result = value == min ? max : value - 1;
  }
  return result;
};

/**
 * 金额转换大写
 * @param money
 * @returns
 */
export const changeNumMoneyToChinese = (money: any) => {
  let cnNums = new Array('零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'); //汉字的数字
  let cnIntRadice = new Array('', '拾', '佰', '仟'); //基本单位
  let cnIntUnits = new Array('', '万', '亿', '兆'); //对应整数部分扩展单位
  let cnDecUnits = new Array('角', '分', '毫', '厘'); //对应小数部分单位
  // let cnInteger = '整'; //整数金额时后面跟的字符
  // let cnIntLast = '元'; //整型完以后的单位
  let maxNum = 999999999999999.9999; //最大处理的数字
  let IntegerNum; //金额整数部分
  let DecimalNum; //金额小数部分
  let ChineseStr = ''; //输出的中文金额字符串
  let parts; //分离金额后用的数组，预定义
  let Symbol = ''; //正负值标记
  if (money == '') {
    return '';
  }

  money = parseFloat(money);
  if (money >= maxNum) {
    message.error('超出最大处理数字');
    return '';
  }
  if (money == 0) {
    // ChineseStr = cnNums[0] + cnIntLast + cnInteger;
    ChineseStr = cnNums[0];
    return ChineseStr;
  }
  if (money < 0) {
    money = -money;
    Symbol = '负 ';
  }
  money = money.toString(); //转换为字符串
  if (money.indexOf('.') == -1) {
    IntegerNum = money;
    DecimalNum = '';
  } else {
    parts = money.split('.');
    IntegerNum = parts[0];
    DecimalNum = parts[1].substr(0, 4);
  }
  if (parseInt(IntegerNum, 10) > 0) {
    //获取整型部分转换
    let zeroCount = 0;
    let IntLen = IntegerNum.length;
    for (let i = 0; i < IntLen; i++) {
      let n = IntegerNum.substr(i, 1);
      let p = IntLen - i - 1;
      let q = p / 4;
      let m = p % 4;
      if (n == '0') {
        zeroCount++;
      } else {
        if (zeroCount > 0) {
          ChineseStr += cnNums[0];
        }
        zeroCount = 0; //归零
        ChineseStr += cnNums[parseInt(n)] + cnIntRadice[m];
      }
      if (m == 0 && zeroCount < 4) {
        ChineseStr += cnIntUnits[q];
      }
    }
    // ChineseStr += cnIntLast;
    ChineseStr;
    //整型部分处理完毕
  }
  if (DecimalNum != '') {
    //小数部分
    let decLen = DecimalNum.length;
    for (let i = 0; i < decLen; i++) {
      let n = DecimalNum.substr(i, 1);
      if (n != '0') {
        ChineseStr += cnNums[Number(n)] + cnDecUnits[i];
      }
    }
  }
  if (ChineseStr == '') {
    // ChineseStr += cnNums[0] + cnIntLast + cnInteger;
    ChineseStr += cnNums[0];
  } else if (DecimalNum == '') {
    // ChineseStr += cnInteger;
    ChineseStr;
  }
  ChineseStr = Symbol + ChineseStr;

  return ChineseStr;
};

/** 处理折叠表格图标 */
export const manageTableExpandIcon = (props: any) => {
  let iconDom: ReactElement = <CaretRightOutlined />;
  if (props.expanded) {
    iconDom = <CaretDownOutlined />;
  }

  let divCss: React.CSSProperties = {
    // float: 'left',
    marginRight: '5px',
  };
  if (!props?.record?.children) {
    divCss['visibility'] = 'hidden';
  }

  return (
    <span
      onClick={(e) => {
        props.onExpand(props.record, e);
      }}
      style={{
        ...divCss,
      }}
    >
      <span>{iconDom}</span>
    </span>
  );
};

/**
 * 详情参数处理
 * @param loadMap  需要翻译的数据字典
 * @param organize 需要翻译的组织机构信息
 * @param area 需要翻译的省市县信息
 * @returns
 */
export const commonDetailPayload = (transInfo: Record<string, any>) => {
  const translateObj: Record<string, any> = {
    ...transInfo,
    areaFlag: transInfo?.areaTransName ? true : false,
  };

  return {
    // dicTypeIds: loapCode.toString(),
    ...translateObj,
  };
};

/** 日期去除时分秒 */
export const removeDateHmsStr = (dateStr: string) => {
  if (dateStr) {
    // const timeStr: string[] = dateStr?.split(' ');
    // return timeStr?.[0];
    const timeStr: string = moment(dateStr)?.format('YYYY-MM-DD');
    return timeStr;
  } else {
    return '--';
  }
};

/** 阿拉伯数字转中文大写 */
export const arabicToChinese = (num: number) => {
  if (!Number.isInteger(num) && num < 0) {
    throw Error('请输入自然数');
  }
  const digits = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'];
  const positions = ['', '十', '百', '千', '万', '十万', '百万', '千万', '亿', '十亿', '百亿', '千亿'];
  const charArray = String(num).split('');
  let result = '';
  let prevIsZero = false;
  //处理0  deal zero
  for (let i = 0; i < charArray.length; i++) {
    const ch = charArray[i];
    if (ch !== '0' && !prevIsZero) {
      result += digits[parseInt(ch)] + positions[charArray.length - i - 1];
    } else if (ch === '0') {
      prevIsZero = true;
    } else if (ch !== '0' && prevIsZero) {
      result += '零' + digits[parseInt(ch)] + positions[charArray.length - i - 1];
    }
  }
  //处理十 deal ten
  if (num < 100) {
    result = result.replace('一十', '十');
  }
  return result;
};

/**
 * 处理渲染水印
 * @param domId  渲染水印的domid
 * @param isShow 渲染水印或卸载
 */
export const renderWaterMarkDom = (domId: string, isShow: boolean) => {
  // if (isShow) {
  Watermark?.init({
    watermark_txt: isShow ? `${getUserName()} ${moment()?.format('YYYY/MM/DD')}` : ' ', //水印内容
    watermark_width: 200, //水印宽度
    watermark_angle: 30, //水印倾斜程度
    watermark_x_space: 120, //水印x轴间距
    watermark_y_space: 130, //水印y轴间距
    watermark_parent_node: document.getElementById(domId), //水印挂在dom节点，默认body
  });
  // } else {
  //   Watermark.remove()
  // }
};

/** 文件流导出数据 */
export const fieldFlowExport = (flowInfo: any, fieldName: string) => {
  message.success('文件生成中...');
  // data为blob格式
  let blob = new Blob([flowInfo]);
  let downloadElement = document.createElement('a');
  let href = window.URL.createObjectURL(blob);
  downloadElement.href = href;
  downloadElement.download = fieldName;
  document.body.appendChild(downloadElement);
  downloadElement.click();
  document.body.removeChild(downloadElement);
  window.URL.revokeObjectURL(href);
};

/** 生成流水单号 */
export const getInvoiceCode = (BusinessCode: string) => {
  const positionInfo: Record<string, any> = getPersonalInfo()?.mpositionList?.find((item: any) => item?.id == getPosIDs());
  if (positionInfo) {
    const { departmentCode = '--', companyCode = '--' } = positionInfo;
    return 'HL' + companyCode + departmentCode + BusinessCode + moment()?.format('YYYY')?.slice(2) + moment()?.format('YYYYMMDDHH')?.slice(4, 6);
  } else {
    return '--';
  }
};

/** 判断当前人是否可以撤回 */
export const isRevocationBtn = (flowDetailInfo, flowBusinessType) => {
  /**撤回按钮编码*/
  const BackButtonVal = `${getTenantID()}${ILoadMapTypeAll.ALLFLOW_HANDRESULT}1005`;
  /**审核中-流程状态*/
  const AuditState = `${getTenantID()}${ILoadMapTypeAll.ALLFLOW_CHECKRESULT}1000`;
  /**编制中-流程状态*/
  const WeaveState = `${getTenantID()}${ILoadMapTypeAll.ALLFLOW_CHECKRESULT}1001`;

  /**当前办理任务信息*/
  let taskList: Record<string, any>[] | null = flowDetailInfo?.paramObject?.[flowBusinessType]?.mactivitiTaskList;
  /**历史办理任务信息*/
  let localTaskList: Record<string, any>[] | null = flowDetailInfo?.paramObject?.[flowBusinessType]?.mactivitiHisProcinstList?.[0]?.mactivitiHisTaskInstList;
  /**流程当前状态*/
  let taskCheckState: string | null = flowDetailInfo?.paramObject?.[flowBusinessType]?.mactivitiHisProcinstList?.[0]?.checkResult;

  // 判断详情和任务列表
  if (flowDetailInfo?.id && taskList) {
    // 普通任务处理
    if (taskList?.length == 1 && taskList?.[0]?.taskIsSign == 0) {
      // 当前任务节点
      const taskNode = taskList?.[0];
      // 当前任务节点身上返回的操作按钮
      const transacBtnList = taskNode?.msequenceFlowList;
      // 首先先确定按钮列表中是否有撤回按钮
      const isThereBtn = transacBtnList?.find((item) => item?.flowValue == BackButtonVal);
      // 如果没有撤回按钮，直接返回 false
      if (!isThereBtn) return false;
      /**
       * 如果有，那么去历史办理节点找第二个【上一个人】
       * 条件如果历史办理节点数组存在 && 数组大于等于2（发起人算在第一个，所有要用2）&& 流程状态为审核中 | 编制中
       * */
      if (localTaskList && localTaskList?.length >= 2 && (taskCheckState == AuditState || taskCheckState == WeaveState)) {
        /**
         * 寻找上一个节点
         * 条件1：第一个是发起人节点，所以要排除
         * 条件2：assigneeID不存在的时候，说明是自动办理节点，要排除
         * */
        const preNode = localTaskList?.find((item, index) => {
          if (index !== 0 && item?.assigneeID && item?.taskIsSign !== null) {
            return item;
          }
        });
        // console.log('preNode=============1============preNode', preNode);
        // 当上一个节点[preNode]的 taskIsSign==0 说明上个任务是普通节点任务
        if (preNode?.taskIsSign == 0) {
          // 普通任务 办理人和办理岗位是当前人则可以撤回
          if (preNode?.assigneeID == getUserID() && preNode?.assigneePositionID == getPosIDs()) {
            return {
              revocainfo: isThereBtn,
              handlebtnlist: transacBtnList,
              completeuserobj: taskNode,
            };
          }
          // 当上一个节点[preNode]的 taskIsSign==1 说明上个任务是会签节点任务
        } else if (preNode?.taskIsSign == 1) {
          // 会签任务
          // if (preNode?.comment != '撤回') {
          if (preNode?.resultInfo?.indexOf('撤回') == -1) {
            // 上一个任务的key
            const taskKey = preNode?.taskDefKey;
            // 上一个会签任务集合
            const counterLocalTaskList = localTaskList?.filter((item) => item?.taskDefKey == taskKey);
            // 当前人是否在上一个会签集合中存在
            const flagObj = counterLocalTaskList?.find((item) => item?.assigneeID == getUserID() && item?.assigneePositionID == getPosIDs());
            if (flagObj) {
              return {
                revocainfo: isThereBtn,
                handlebtnlist: transacBtnList,
                iscounterobj: { taskIsSign: 1, taskList, isCurrent: true }, //[taskList: counterLocalTaskList]
                completeuserobj: taskNode,
              };
            }
          }
        }
      } else {
        return false;
      }
    }

    // 会签任务处理
    if (taskList?.length >= 1 && taskList?.[0]?.taskIsSign == 1) {
      /**
       * @title 从历史任务中找数据【条件1:是会签任务，条件2:未办理】
       * [解释：流程中的节点，如果有会签，要么是已经办过的，要么是后面未办理的，后面未办理数据的还不会存在在历史节点信息里]
       * */
      const taskKey = taskList[0].taskDefKey;
      const transacBtnList = taskList[0]?.msequenceFlowList;
      const localCounterTaskList = localTaskList?.filter((item) => item?.taskIsSign == 1 && taskKey == item?.taskDefKey && !item?.comment);
      const isThereBtn = transacBtnList?.find((item) => item?.flowValue == BackButtonVal);
      const preNode = localTaskList?.find((item) => item?.taskDefKey != taskKey && item?.taskIsSign !== null);
      // console.log('preNode=============2============preNode', preNode);
      if (
        localCounterTaskList?.length === taskList?.length && // 说明会签任务，一个都没有办理
        isThereBtn &&
        preNode?.assigneeID == getUserID() &&
        preNode?.assigneePositionID == getPosIDs() &&
        preNode?.resultInfo?.indexOf('撤回') == -1
        // preNode?.comment != '撤回'
      ) {
        // 说明会签任务，一个都没有办理
        return {
          revocainfo: isThereBtn,
          handlebtnlist: transacBtnList,
          iscounterobj: { taskIsSign: 1, taskList, isCurrent: false },
        };
      }
    }
  }
  return false;
};

/** 递归方法删除树节点 */
export const removeNodeById = (tree, key, idToRemove) => {
  // 使用 filter 方法过滤掉 id 为 idToRemove 的节点
  return tree.filter((node) => {
    if (node[key] === idToRemove) {
      return false; // 过滤掉这个节点
    } else if (node.children) {
      // 如果有子节点，递归处理子节点
      node.children = removeNodeById(node.children, key, idToRemove);
      return true; // 保留这个节点（如果子节点中有匹配的节点，它们会被过滤掉）
    }
    return true; // 保留没有子节点且 id 不匹配的节点
  });
};
